/*
 * config.h
 *
 * Copyright (C) 2008, 2009
 *
 * Lukasz Bieniasz-Krzywiec
 * Dariusz Leniowski
 *
 * plik konfiguracyjny
 */

#ifndef CONFIG_H_
#define CONFIG_H_

#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>

#include <vector>
#include <algorithm>

#include <stdint.h>
#include <omp.h>

#include <sys/time.h>

using namespace std;


/*
 * DEFINICJE STALYCH:
 */

/* Generatory liczb pseudolosowych */
#define RANDOM_CPP 1

/* Rodzaje Fwwk */
#define FWWK_MIN 1
#define FWWK_MAX 2
#define FWWK_MEAN 3

/* Rodzaje reputacji */
#define REPUTACJA_BRAK 1
#define REPUTACJA_PODSTAWOWA 2

/* Rodzaje osobnikow */
#define MAX_RODZAJOW              1000000

#define OSOBNIK_ALLC              100
#define OSOBNIK_ALLD              200
#define OSOBNIK_NIETOPERZ_ZLY     300
#define OSOBNIK_NIETOPERZ_DOBRY   400

#define LUBI_LOSOWY               100
#define LUBI_WSZYSTKICH           200
#define LUBI_WSPOLPRACE           300
#define LUBI_WSPOLPRACE2          400
#define LUBI_FITNESS              500

#define OSOBNIK_ALLC_LOSOWO       100100
#define OSOBNIK_ALLC_WSZYSTO      100200
#define OSOBNIK_ALLC_WSPOLPRACA   100300
#define OSOBNIK_ALLC_WSPOLPRACA2  100400
#define OSOBNIK_ALLC_FITNESS      100500
#define OSOBNIK_ALLD_LOSOWO       200100
#define OSOBNIK_ALLD_WSZYSTO      200200
#define OSOBNIK_ALLD_WSPOLPRACA   200300
#define OSOBNIK_ALLD_WSPOLPRACA2  200400
#define OSOBNIK_ALLD_FITNESS      200500
#define OSOBNIK_TFT_LOSOWO        400100
#define OSOBNIK_TFT_WSZYSTO       400200
#define OSOBNIK_TFT_WSPOLPRACA    400300
#define OSOBNIK_TFT_WSPOLPRACA2   400400
#define OSOBNIK_TFT_FITNESS       400500

/* Rodzaje fitness */
#define FITNESS_STALY 1
#define FITNESS_OSTATNIA_WYPLATA 2
#define FITNESS_OSTATNIA_WYPLATA_ZNORMALIZOWANA 3
#define FITNESS_LICZEBNOSC_RODZAJU 4
#define FITNESS_WYPLATA_RODZAJU 5
#define FITNESS_WYPLATA_ZNORMALIZOWANA_RODZAJU 6

/* Rodzaje selekcji */
#define SELEKCJA_PROSTA 1
#define SELEKCJA_IMITACJA 2
#define SELEKCJA_IMITACJA_WSZYSTKIE 3
#define SELEKCJA_PROCES_MORANA 4
#define SELEKCJA_PROCES_MORANA_ARTYKUL 5
#define SELEKCJA_PROCES_MORANA_WSZYSTKIE_ARTYKUL 6
#define SELEKCJA_IMITACJA_RODZAJOW 7
#define SELEKCJA_IMITACJA_RODZAJOW_WSZYSTKIE 8
#define SELEKCJA_PROCES_MORANA_DAREK 9
#define SELEKCJA_PROCES_MORANA_WSZYSTKIE_DAREK 10
#define SELEKCJA_IMITACJA_RODZAJOW2 11
#define SELEKCJA_IMITACJA_RODZAJOW2_WSZYSTKIE 12
#define SELEKCJA_IMITACJA_RODZAJOW3 13
#define SELEKCJA_IMITACJA_RODZAJOW3_WSZYSTKIE 14

/* Rodzaje grafow dla osobnika mieszanego */
#define GRAF_PELNY 1
#define GRAF_PIERSCIEN 2
#define GRAF_KRATA4 4
#define GRAF_KRATA6 6
#define GRAF_KRATA8 8
#define GRAF_KRATA_3D 9

/* Rodzaje symulacji */
#define LOSOWANIE 1
#define WARTOSC_OCZEKIWANA 2

/* Kto gra w danej epoce */
#define WSZYSTKIE_WIERZCHOLKI 1
#define JEDEN_WIERZCHOLEK 2
#define WSZYSCY_SASIEDZI 1
#define JEDEN_SASIAD 2


/*
 * DEFINICJE TYPOW
 */

typedef double real;
#define REALF "%lf"

/*
 * PRZYDATNE MAKRA:
 */

#define REP(i,n) for(int i=0;i<(n);++i)
#define FOREN(nazwa) for((nazwa) = 0; (nazwa) < N; (nazwa) ++)

#define blad(str) do { fprintf(stderr, "BLAD: %s", (str)); exit(-1); } while(0)


/*
 * MACROS TO HELP DEBUGGING:
 */

#undef PDEBUG
#undef ASSERT
#undef PROFILE

#ifdef DEBUG
# ifdef __KERNEL__
    /* This one if debugging is on, and kernel space */
#   define PDEBUG(fmt, args...) printk(KERN_CRIT ": " fmt, ## args)
# else
    /* This one for user space */
#   define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
# endif

# define ASSERT(x) do {\
    if (!(x)) {\
	   PDEBUG("Assertion failed at line %d in file %s: " #x "\n", __LINE__, __FILE__);\
		exit(-1);\
	}\
  } while(0)

# include <sys/time.h>

# define PROFILE(x) do {\
    struct timeval timev1, timev2;\
    gettimeofday(&timev1, NULL);\
    x;\
    gettimeofday(&timev2, NULL);\
    float time_seconds = timev2.tv_sec - timev1.tv_sec;\
    time_seconds += 0.000001 * (timev2.tv_usec - timev1.tv_usec);\
    PDEBUG(#x " at line %d in file %s: %f s\n", __LINE__, __FILE__, time_seconds);\
  } while(0)
  
#	define PROFILE_init struct timeval timev1, timev2
  
# define PROFILE_start do {\
    gettimeofday(&timev1, NULL);\
} while(0)
 	
#	define PROFILE_end do {\
    gettimeofday(&timev2, NULL);\
    float time_seconds = timev2.tv_sec - timev1.tv_sec;\
    time_seconds += 0.000001 * (timev2.tv_usec - timev1.tv_usec);\
    PDEBUG("at line %d in file %s: %f s\n", __LINE__, __FILE__, time_seconds);\
  } while(0)
#else
# define PDEBUG(fmt, args...) /* not debugging: nothing */
# define ASSERT(x)
# define PROFILE(x) x;
#endif

#define Q PDEBUG("%s:%d\n", __FILE__, __LINE__)
#define QP PDEBUG("%d:%s:%d\n", omp_get_thread_num(), __FILE__, __LINE__)

#endif /* CONFIG_H_ */
